// Copyright (c) Lawrence Livermore National Security, LLC and other VisIt
// Project developers.  See the top-level LICENSE file for dates and other
// details.  No copyright assignment is required to contribute to VisIt.

#include <MeshManagementAttributes.h>
#include <DataNode.h>

//
// Enum conversion methods for MeshManagementAttributes::DiscretizationModes
//

static const char *DiscretizationModes_strings[] = {
"Uniform", "Adaptive", "MultiPass"
};

std::string
MeshManagementAttributes::DiscretizationModes_ToString(MeshManagementAttributes::DiscretizationModes t)
{
    int index = int(t);
    if(index < 0 || index >= 3) index = 0;
    return DiscretizationModes_strings[index];
}

std::string
MeshManagementAttributes::DiscretizationModes_ToString(int t)
{
    int index = (t < 0 || t >= 3) ? 0 : t;
    return DiscretizationModes_strings[index];
}

bool
MeshManagementAttributes::DiscretizationModes_FromString(const std::string &s, MeshManagementAttributes::DiscretizationModes &val)
{
    val = MeshManagementAttributes::Uniform;
    for(int i = 0; i < 3; ++i)
    {
        if(s == DiscretizationModes_strings[i])
        {
            val = (DiscretizationModes)i;
            return true;
        }
    }
    return false;
}

// ****************************************************************************
// Method: MeshManagementAttributes::MeshManagementAttributes
//
// Purpose:
//   Init utility for the MeshManagementAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

void MeshManagementAttributes::Init()
{
    discretizationTolerance.push_back(0.02);
    discretizationTolerance.push_back(0.025);
    discretizationTolerance.push_back(0.05);
    discretizationMode = Uniform;
    discretizeBoundaryOnly = false;
    passNativeCSG = false;

    MeshManagementAttributes::SelectAll();
}

// ****************************************************************************
// Method: MeshManagementAttributes::MeshManagementAttributes
//
// Purpose:
//   Copy utility for the MeshManagementAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

void MeshManagementAttributes::Copy(const MeshManagementAttributes &obj)
{
    discretizationTolerance = obj.discretizationTolerance;
    discretizationToleranceX = obj.discretizationToleranceX;
    discretizationToleranceY = obj.discretizationToleranceY;
    discretizationToleranceZ = obj.discretizationToleranceZ;
    discretizationMode = obj.discretizationMode;
    discretizeBoundaryOnly = obj.discretizeBoundaryOnly;
    passNativeCSG = obj.passNativeCSG;

    MeshManagementAttributes::SelectAll();
}

// Type map format string
const char *MeshManagementAttributes::TypeMapFormatString = MESHMANAGEMENTATTRIBUTES_TMFS;
const AttributeGroup::private_tmfs_t MeshManagementAttributes::TmfsStruct = {MESHMANAGEMENTATTRIBUTES_TMFS};


// ****************************************************************************
// Method: MeshManagementAttributes::MeshManagementAttributes
//
// Purpose:
//   Default constructor for the MeshManagementAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

MeshManagementAttributes::MeshManagementAttributes() :
    AttributeSubject(MeshManagementAttributes::TypeMapFormatString)
{
    MeshManagementAttributes::Init();
}

// ****************************************************************************
// Method: MeshManagementAttributes::MeshManagementAttributes
//
// Purpose:
//   Constructor for the derived classes of MeshManagementAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

MeshManagementAttributes::MeshManagementAttributes(private_tmfs_t tmfs) :
    AttributeSubject(tmfs.tmfs)
{
    MeshManagementAttributes::Init();
}

// ****************************************************************************
// Method: MeshManagementAttributes::MeshManagementAttributes
//
// Purpose:
//   Copy constructor for the MeshManagementAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

MeshManagementAttributes::MeshManagementAttributes(const MeshManagementAttributes &obj) :
    AttributeSubject(MeshManagementAttributes::TypeMapFormatString)
{
    MeshManagementAttributes::Copy(obj);
}

// ****************************************************************************
// Method: MeshManagementAttributes::MeshManagementAttributes
//
// Purpose:
//   Copy constructor for derived classes of the MeshManagementAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

MeshManagementAttributes::MeshManagementAttributes(const MeshManagementAttributes &obj, private_tmfs_t tmfs) :
    AttributeSubject(tmfs.tmfs)
{
    MeshManagementAttributes::Copy(obj);
}

// ****************************************************************************
// Method: MeshManagementAttributes::~MeshManagementAttributes
//
// Purpose:
//   Destructor for the MeshManagementAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

MeshManagementAttributes::~MeshManagementAttributes()
{
    // nothing here
}

// ****************************************************************************
// Method: MeshManagementAttributes::operator =
//
// Purpose:
//   Assignment operator for the MeshManagementAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

MeshManagementAttributes&
MeshManagementAttributes::operator = (const MeshManagementAttributes &obj)
{
    if (this == &obj) return *this;

    MeshManagementAttributes::Copy(obj);

    return *this;
}

// ****************************************************************************
// Method: MeshManagementAttributes::operator ==
//
// Purpose:
//   Comparison operator == for the MeshManagementAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

bool
MeshManagementAttributes::operator == (const MeshManagementAttributes &obj) const
{
    // Create the return value
    return ((discretizationTolerance == obj.discretizationTolerance) &&
            (discretizationToleranceX == obj.discretizationToleranceX) &&
            (discretizationToleranceY == obj.discretizationToleranceY) &&
            (discretizationToleranceZ == obj.discretizationToleranceZ) &&
            (discretizationMode == obj.discretizationMode) &&
            (discretizeBoundaryOnly == obj.discretizeBoundaryOnly) &&
            (passNativeCSG == obj.passNativeCSG));
}

// ****************************************************************************
// Method: MeshManagementAttributes::operator !=
//
// Purpose:
//   Comparison operator != for the MeshManagementAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

bool
MeshManagementAttributes::operator != (const MeshManagementAttributes &obj) const
{
    return !(this->operator == (obj));
}

// ****************************************************************************
// Method: MeshManagementAttributes::TypeName
//
// Purpose:
//   Type name method for the MeshManagementAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

const std::string
MeshManagementAttributes::TypeName() const
{
    return "MeshManagementAttributes";
}

// ****************************************************************************
// Method: MeshManagementAttributes::CopyAttributes
//
// Purpose:
//   CopyAttributes method for the MeshManagementAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

bool
MeshManagementAttributes::CopyAttributes(const AttributeGroup *atts)
{
    if(TypeName() != atts->TypeName())
        return false;

    // Call assignment operator.
    const MeshManagementAttributes *tmp = (const MeshManagementAttributes *)atts;
    *this = *tmp;

    return true;
}

// ****************************************************************************
// Method: MeshManagementAttributes::CreateCompatible
//
// Purpose:
//   CreateCompatible method for the MeshManagementAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

AttributeSubject *
MeshManagementAttributes::CreateCompatible(const std::string &tname) const
{
    AttributeSubject *retval = 0;
    if(TypeName() == tname)
        retval = new MeshManagementAttributes(*this);
    // Other cases could go here too.

    return retval;
}

// ****************************************************************************
// Method: MeshManagementAttributes::NewInstance
//
// Purpose:
//   NewInstance method for the MeshManagementAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

AttributeSubject *
MeshManagementAttributes::NewInstance(bool copy) const
{
    AttributeSubject *retval = 0;
    if(copy)
        retval = new MeshManagementAttributes(*this);
    else
        retval = new MeshManagementAttributes;

    return retval;
}

// ****************************************************************************
// Method: MeshManagementAttributes::SelectAll
//
// Purpose:
//   Selects all attributes.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

void
MeshManagementAttributes::SelectAll()
{
    Select(ID_discretizationTolerance,  (void *)&discretizationTolerance);
    Select(ID_discretizationToleranceX, (void *)&discretizationToleranceX);
    Select(ID_discretizationToleranceY, (void *)&discretizationToleranceY);
    Select(ID_discretizationToleranceZ, (void *)&discretizationToleranceZ);
    Select(ID_discretizationMode,       (void *)&discretizationMode);
    Select(ID_discretizeBoundaryOnly,   (void *)&discretizeBoundaryOnly);
    Select(ID_passNativeCSG,            (void *)&passNativeCSG);
}

///////////////////////////////////////////////////////////////////////////////
// Persistence methods
///////////////////////////////////////////////////////////////////////////////

// ****************************************************************************
// Method: MeshManagementAttributes::CreateNode
//
// Purpose:
//   This method creates a DataNode representation of the object so it can be saved to a config file.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

bool
MeshManagementAttributes::CreateNode(DataNode *parentNode, bool completeSave, bool forceAdd)
{
    if(parentNode == 0)
        return false;

    MeshManagementAttributes defaultObject;
    bool addToParent = false;
    // Create a node for MeshManagementAttributes.
    DataNode *node = new DataNode("MeshManagementAttributes");

    if(completeSave || !FieldsEqual(ID_discretizationTolerance, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("discretizationTolerance", discretizationTolerance));
    }

    if(completeSave || !FieldsEqual(ID_discretizationToleranceX, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("discretizationToleranceX", discretizationToleranceX));
    }

    if(completeSave || !FieldsEqual(ID_discretizationToleranceY, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("discretizationToleranceY", discretizationToleranceY));
    }

    if(completeSave || !FieldsEqual(ID_discretizationToleranceZ, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("discretizationToleranceZ", discretizationToleranceZ));
    }

    if(completeSave || !FieldsEqual(ID_discretizationMode, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("discretizationMode", DiscretizationModes_ToString(discretizationMode)));
    }

    if(completeSave || !FieldsEqual(ID_discretizeBoundaryOnly, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("discretizeBoundaryOnly", discretizeBoundaryOnly));
    }

    if(completeSave || !FieldsEqual(ID_passNativeCSG, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("passNativeCSG", passNativeCSG));
    }


    // Add the node to the parent node.
    if(addToParent || forceAdd)
        parentNode->AddNode(node);
    else
        delete node;

    return (addToParent || forceAdd);
}

// ****************************************************************************
// Method: MeshManagementAttributes::SetFromNode
//
// Purpose:
//   This method sets attributes in this object from values in a DataNode
//   representation of the object.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   Thu Dec 20 09:40:39 PDT 2007
//
// Modifications:
//
//   Mark C. Miller, Thu Jan 10 14:55:56 PST 2008
//   Made it backward compatible for older config files.
// ****************************************************************************

void
MeshManagementAttributes::SetFromNode(DataNode *parentNode)
{
    if(parentNode == 0)
        return;

    DataNode *searchNode = parentNode->GetNode("MeshManagementAttributes");
    if(searchNode == 0)
        return;

    DataNode *node;
    if((node = searchNode->GetNode("discretizationTolerance")) != 0)
    {
        if (node->AsDoubleVector().size() == 3)
            SetDiscretizationTolerance(node->AsDoubleVector());
        else
        {
            MeshManagementAttributes tmp;
            SetDiscretizationTolerance(tmp.GetDiscretizationTolerance());
        }
    }
    if((node = searchNode->GetNode("discretizationToleranceX")) != 0)
        SetDiscretizationToleranceX(node->AsDoubleVector());
    if((node = searchNode->GetNode("discretizationToleranceY")) != 0)
        SetDiscretizationToleranceY(node->AsDoubleVector());
    if((node = searchNode->GetNode("discretizationToleranceZ")) != 0)
        SetDiscretizationToleranceZ(node->AsDoubleVector());
    if((node = searchNode->GetNode("discretizationMode")) != 0)
    {
        // Allow enums to be int or string in the config file
        if(node->GetNodeType() == INT_NODE)
        {
            int ival = node->AsInt();
            if(ival >= 0 && ival < 2)
                SetDiscretizationMode(DiscretizationModes(ival));
        }
        else if(node->GetNodeType() == STRING_NODE)
        {
            DiscretizationModes value;
            if(DiscretizationModes_FromString(node->AsString(), value))
                SetDiscretizationMode(value);
        }
    }
    if((node = searchNode->GetNode("discretizeBoundaryOnly")) != 0)
        SetDiscretizeBoundaryOnly(node->AsBool());
    if((node = searchNode->GetNode("passNativeCSG")) != 0)
        SetPassNativeCSG(node->AsBool());
}
///////////////////////////////////////////////////////////////////////////////
// Set property methods
///////////////////////////////////////////////////////////////////////////////

void
MeshManagementAttributes::SetDiscretizationTolerance(const doubleVector &discretizationTolerance_)
{
    discretizationTolerance = discretizationTolerance_;
    Select(ID_discretizationTolerance, (void *)&discretizationTolerance);
}

void
MeshManagementAttributes::SetDiscretizationToleranceX(const doubleVector &discretizationToleranceX_)
{
    discretizationToleranceX = discretizationToleranceX_;
    Select(ID_discretizationToleranceX, (void *)&discretizationToleranceX);
}

void
MeshManagementAttributes::SetDiscretizationToleranceY(const doubleVector &discretizationToleranceY_)
{
    discretizationToleranceY = discretizationToleranceY_;
    Select(ID_discretizationToleranceY, (void *)&discretizationToleranceY);
}

void
MeshManagementAttributes::SetDiscretizationToleranceZ(const doubleVector &discretizationToleranceZ_)
{
    discretizationToleranceZ = discretizationToleranceZ_;
    Select(ID_discretizationToleranceZ, (void *)&discretizationToleranceZ);
}

void
MeshManagementAttributes::SetDiscretizationMode(MeshManagementAttributes::DiscretizationModes discretizationMode_)
{
    discretizationMode = discretizationMode_;
    Select(ID_discretizationMode, (void *)&discretizationMode);
}

void
MeshManagementAttributes::SetDiscretizeBoundaryOnly(bool discretizeBoundaryOnly_)
{
    discretizeBoundaryOnly = discretizeBoundaryOnly_;
    Select(ID_discretizeBoundaryOnly, (void *)&discretizeBoundaryOnly);
}

void
MeshManagementAttributes::SetPassNativeCSG(bool passNativeCSG_)
{
    passNativeCSG = passNativeCSG_;
    Select(ID_passNativeCSG, (void *)&passNativeCSG);
}

///////////////////////////////////////////////////////////////////////////////
// Get property methods
///////////////////////////////////////////////////////////////////////////////

const doubleVector &
MeshManagementAttributes::GetDiscretizationTolerance() const
{
    return discretizationTolerance;
}

doubleVector &
MeshManagementAttributes::GetDiscretizationTolerance()
{
    return discretizationTolerance;
}

const doubleVector &
MeshManagementAttributes::GetDiscretizationToleranceX() const
{
    return discretizationToleranceX;
}

doubleVector &
MeshManagementAttributes::GetDiscretizationToleranceX()
{
    return discretizationToleranceX;
}

const doubleVector &
MeshManagementAttributes::GetDiscretizationToleranceY() const
{
    return discretizationToleranceY;
}

doubleVector &
MeshManagementAttributes::GetDiscretizationToleranceY()
{
    return discretizationToleranceY;
}

const doubleVector &
MeshManagementAttributes::GetDiscretizationToleranceZ() const
{
    return discretizationToleranceZ;
}

doubleVector &
MeshManagementAttributes::GetDiscretizationToleranceZ()
{
    return discretizationToleranceZ;
}

MeshManagementAttributes::DiscretizationModes
MeshManagementAttributes::GetDiscretizationMode() const
{
    return DiscretizationModes(discretizationMode);
}

bool
MeshManagementAttributes::GetDiscretizeBoundaryOnly() const
{
    return discretizeBoundaryOnly;
}

bool
MeshManagementAttributes::GetPassNativeCSG() const
{
    return passNativeCSG;
}

///////////////////////////////////////////////////////////////////////////////
// Select property methods
///////////////////////////////////////////////////////////////////////////////

void
MeshManagementAttributes::SelectDiscretizationTolerance()
{
    Select(ID_discretizationTolerance, (void *)&discretizationTolerance);
}

void
MeshManagementAttributes::SelectDiscretizationToleranceX()
{
    Select(ID_discretizationToleranceX, (void *)&discretizationToleranceX);
}

void
MeshManagementAttributes::SelectDiscretizationToleranceY()
{
    Select(ID_discretizationToleranceY, (void *)&discretizationToleranceY);
}

void
MeshManagementAttributes::SelectDiscretizationToleranceZ()
{
    Select(ID_discretizationToleranceZ, (void *)&discretizationToleranceZ);
}

///////////////////////////////////////////////////////////////////////////////
// Keyframing methods
///////////////////////////////////////////////////////////////////////////////

// ****************************************************************************
// Method: MeshManagementAttributes::GetFieldName
//
// Purpose:
//   This method returns the name of a field given its index.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

std::string
MeshManagementAttributes::GetFieldName(int index) const
{
    switch (index)
    {
    case ID_discretizationTolerance:  return "discretizationTolerance";
    case ID_discretizationToleranceX: return "discretizationToleranceX";
    case ID_discretizationToleranceY: return "discretizationToleranceY";
    case ID_discretizationToleranceZ: return "discretizationToleranceZ";
    case ID_discretizationMode:       return "discretizationMode";
    case ID_discretizeBoundaryOnly:   return "discretizeBoundaryOnly";
    case ID_passNativeCSG:            return "passNativeCSG";
    default:  return "invalid index";
    }
}

// ****************************************************************************
// Method: MeshManagementAttributes::GetFieldType
//
// Purpose:
//   This method returns the type of a field given its index.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

AttributeGroup::FieldType
MeshManagementAttributes::GetFieldType(int index) const
{
    switch (index)
    {
    case ID_discretizationTolerance:  return FieldType_doubleVector;
    case ID_discretizationToleranceX: return FieldType_doubleVector;
    case ID_discretizationToleranceY: return FieldType_doubleVector;
    case ID_discretizationToleranceZ: return FieldType_doubleVector;
    case ID_discretizationMode:       return FieldType_enum;
    case ID_discretizeBoundaryOnly:   return FieldType_bool;
    case ID_passNativeCSG:            return FieldType_bool;
    default:  return FieldType_unknown;
    }
}

// ****************************************************************************
// Method: MeshManagementAttributes::GetFieldTypeName
//
// Purpose:
//   This method returns the name of a field type given its index.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

std::string
MeshManagementAttributes::GetFieldTypeName(int index) const
{
    switch (index)
    {
    case ID_discretizationTolerance:  return "doubleVector";
    case ID_discretizationToleranceX: return "doubleVector";
    case ID_discretizationToleranceY: return "doubleVector";
    case ID_discretizationToleranceZ: return "doubleVector";
    case ID_discretizationMode:       return "enum";
    case ID_discretizeBoundaryOnly:   return "bool";
    case ID_passNativeCSG:            return "bool";
    default:  return "invalid index";
    }
}

// ****************************************************************************
// Method: MeshManagementAttributes::FieldsEqual
//
// Purpose:
//   This method compares two fields and return true if they are equal.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

bool
MeshManagementAttributes::FieldsEqual(int index_, const AttributeGroup *rhs) const
{
    const MeshManagementAttributes &obj = *((const MeshManagementAttributes*)rhs);
    bool retval = false;
    switch (index_)
    {
    case ID_discretizationTolerance:
        {  // new scope
        retval = (discretizationTolerance == obj.discretizationTolerance);
        }
        break;
    case ID_discretizationToleranceX:
        {  // new scope
        retval = (discretizationToleranceX == obj.discretizationToleranceX);
        }
        break;
    case ID_discretizationToleranceY:
        {  // new scope
        retval = (discretizationToleranceY == obj.discretizationToleranceY);
        }
        break;
    case ID_discretizationToleranceZ:
        {  // new scope
        retval = (discretizationToleranceZ == obj.discretizationToleranceZ);
        }
        break;
    case ID_discretizationMode:
        {  // new scope
        retval = (discretizationMode == obj.discretizationMode);
        }
        break;
    case ID_discretizeBoundaryOnly:
        {  // new scope
        retval = (discretizeBoundaryOnly == obj.discretizeBoundaryOnly);
        }
        break;
    case ID_passNativeCSG:
        {  // new scope
        retval = (passNativeCSG == obj.passNativeCSG);
        }
        break;
    default: retval = false;
    }

    return retval;
}

///////////////////////////////////////////////////////////////////////////////
// User-defined methods.
///////////////////////////////////////////////////////////////////////////////

